package view;

import org.lwjgl.input.Mouse;

import com.threed.jpct.Camera;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;
import engine.Keyboard;

public class SpaceCamera {
	private Camera camera;
	
	public Camera getCamera() {
		return camera;
	}

	public void setCamera(Camera camera) {
		this.camera = camera;
	}

	private Object3D cameraHandler;
	public Object3D getCameraHandler() {
		return cameraHandler;
	}

	public void setCameraHandler(Object3D cameraHandler) {
		this.cameraHandler = cameraHandler;
	}
	
	private float verticalRotation = 0.0f;
	private float horizontalRotation = 0.0f;
	private float distance;
	
	private final float DEG90_IN_RAD = 1.57f;
	
	//camera properties, default initialization ready-to-use
	private float speed = 0.01f;
	private float zoomSpeed = 0.1f;
	private float minDistance = 50.0f;
	private float maxDistance = 200.0f;
	private float keyZoomSpeed = 2.0f;
	private float keyRotateSpeed = 0.04f;
	
	public SpaceCamera(Camera camera){
		this.camera = camera;
		
		distance = maxDistance;
		cameraHandler = Object3D.createDummyObj();
		setDistance();
	}
	
	private void setDistance(){
		cameraHandler.getTranslationMatrix().setIdentity();
		cameraHandler.translate(0, 0, distance);
		cameraHandler.setRotationPivot(new SimpleVector(0,0,-distance));
		camera.setPositionToCenter(cameraHandler);
		camera.lookAt(SimpleVector.ORIGIN);
	}
	
	private void setRotation(){
		cameraHandler.getRotationMatrix().setIdentity();
		cameraHandler.rotateAxis(cameraHandler.getXAxis(), verticalRotation);
		cameraHandler.rotateY(horizontalRotation);
	}
	
	public void update(){
		//handleKeys();
		rotate();
		zoom();
	}
	
	private void rotate(){
		if(Mouse.isButtonDown(1)){
			int dx = Mouse.getDX();
			int dy = Mouse.getDY();
			
			verticalRotation += speed * dy;
			horizontalRotation += speed * dx;
			
			dx = dy = 0;	
		}
		
		if(Keyboard.RIGHT_PRESSED)
			horizontalRotation += keyRotateSpeed;
		if(Keyboard.LEFT_PRESSED)
			horizontalRotation -= keyRotateSpeed;
		if(Keyboard.DOWN_PRESSED)
			verticalRotation += keyRotateSpeed;
		if(Keyboard.UP_PRESSED)
			verticalRotation -= keyRotateSpeed;
		
		if(verticalRotation >= DEG90_IN_RAD)
			verticalRotation = DEG90_IN_RAD;
		
		if(verticalRotation <= -DEG90_IN_RAD)
			verticalRotation = -DEG90_IN_RAD;
		
		setRotation();
	}
	
	private void zoom(){
		float zoom = Mouse.getDWheel() * zoomSpeed;
		if(inZoomRange(distance-zoom))
			distance -= zoom;
		
		if(Keyboard.PAGE_DOWN_PRESSED && inZoomRange(distance+keyZoomSpeed)){
			distance += keyZoomSpeed;
		}
		if(Keyboard.PAGE_UP_PRESSED && inZoomRange(distance-keyZoomSpeed)){
			distance -= keyZoomSpeed;
		}
		
		setDistance();
	}
	
	private boolean inZoomRange(float value){
		return (value > minDistance && value < maxDistance) ? true : false;
	}
	
//	private void handleKeys(){
//		KeyState state = null;
//		while((state = keyMapper.poll()) != KeyState.NONE){
//			int code = state.getKeyCode();
//			if(code == KeyEvent.VK_DOWN){
//				DOWN_PRESSED = state.getState();
//			}
//			else if(code == KeyEvent.VK_UP){
//				UP_PRESSED = state.getState();
//			}	
//			else if(code == KeyEvent.VK_LEFT){
//				LEFT_PRESSED = state.getState();
//			}
//			else if(code == KeyEvent.VK_RIGHT){
//				RIGHT_PRESSED = state.getState();
//			}	
//			else if(code == KeyEvent.VK_PAGE_DOWN){
//				PAGE_DOWN_PRESSED = state.getState();
//			}
//			else if(code == KeyEvent.VK_PAGE_UP){
//				PAGE_UP_PRESSED = state.getState();
//			}		
//		}		
//	}

	public float getSpeed() {
		return speed;
	}

	public void setSpeed(float speed) {
		this.speed = speed;
	}

	public float getZoomSpeed() {
		return zoomSpeed;
	}

	public void setZoomSpeed(float zoomSpeed) {
		this.zoomSpeed = zoomSpeed;
	}

	public float getMinDistance() {
		return minDistance;
	}

	public void setMinDistance(float minDistance) {
		this.minDistance = minDistance;
	}

	public float getMaxDistance() {
		return maxDistance;
	}

	public void setMaxDistance(float maxDistance) {
		this.maxDistance = maxDistance;
	}

	public float getKeyZoomSpeed() {
		return keyZoomSpeed;
	}

	public void setKeyZoomSpeed(float keyZoomSpeed) {
		this.keyZoomSpeed = keyZoomSpeed;
	}

	public float getKeyRotateSpeed() {
		return keyRotateSpeed;
	}

	public void setKeyRotateSpeed(float keyRotateSpeed) {
		this.keyRotateSpeed = keyRotateSpeed;
	}
}

